using BepuPhysics.Collidables;
using BepuUtilities;
using System.Diagnostics;
using System.Runtime.CompilerServices;
#if MYCODE
using BepuUtilities.Vectors;
#else
using System.Numerics;
#endif
namespace BepuPhysics
{
    /// <summary>
    /// 结构,用于直接引用静电的属性。
    /// </summary>
    /// <remarks>Note that this type makes no attempt to protect against unsafe modification of static properties.</remarks>
    public struct StaticReference
    {
        /// <summary>
        /// 此引用引用的静电的句柄。
        /// </summary>
        public StaticHandle Handle;
        /// <summary>
        /// 包含静电的集合。
        /// </summary>
        public Statics Statics;

        /// <summary>
        /// 构建新的静电参照系。
        /// </summary>
        /// <param name="Handle">要引用的静电的句柄。</param>
        /// <param name="static">包含静电的集合。</param>
        public StaticReference(StaticHandle handle, Statics statics)
        {
            Handle = handle;
            Statics = statics;
        }

        /// <summary>
        /// 获取静电引用是否存在于静电集中。如果句柄映射到同意句柄指向它的有效内存位置,则为true,否则为false。
        /// </summary>
        public bool Exists
        {
            get
            {
                if (Statics == null || Handle.Value < 0 || Handle.Value >= Statics.HandleToIndex.Length)
                    return false;
                return Statics.IndexToHandle[Statics.HandleToIndex[Handle.Value]].Value == Handle.Value;
            }
        }


        /// <summary>
        /// 获取静态集合中的静电索引。
        /// </summary>
        public int Index
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get { return Statics.HandleToIndex[Handle.Value]; }
        }

        /// <summary>
        /// 获取对静电姿势的引用。
        /// </summary>
        public ref RigidPose Pose
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get
            {
                return ref Statics.Poses[Statics.HandleToIndex[Handle.Value]];
            }
        }

        /// <summary>
        /// 获取对静电的可碰撞的引用。
        /// </summary>
        public ref Collidable Collidable
        {
            [MethodImpl(MethodImplOptions.AggressiveInlining)]
            get
            {
                return ref Statics.Collidables[Statics.HandleToIndex[Handle.Value]];
            }
        }

        /// <summary>
        /// 获取静电的说明。
        /// </summary>
        /// <param name="description">静电的描述。</param>
        public void GetDescription(out StaticDescription description)
        {
            Statics.GetDescription(Handle, out description);
        }

        /// <summary>
        /// 根据描述设置静电的属性。
        /// </summary>
        /// <param name="description">静电的描述。</param>
        public void ApplyDescription(in StaticDescription description)
        {
            Statics.ApplyDescription(Handle, description);
        }

        /// <summary>
        /// 改变静电的形状。
        /// </summary>
        /// <param name="newShape">要用于静电的新形状的索引。</param>
        public void SetShape(TypedIndex newShape)
        {
            Statics.SetShape(Handle, newShape);
        }

        /// <summary>
        /// 获取静电的边框的副本。
        /// </summary>
        public unsafe BoundingBox BoundingBox
        {
            get
            {
                BoundingBox box;
                GetBoundsReferencesFromBroadPhase(out var min, out var max);
                box.Min = *min;
                box.Max = *max;
                return box;
            }
        }

        /// <summary>
        /// 获取直接指向静电的边框的宽阶段中的最小和最大边框的指针。如果静电没有形状,则输出NULL。
        /// </summary>
        /// <param name="min">指向宽阶段中最小边界框的指针。</param>
        /// <param name="max">指向宽阶段中的最大边界框的指针。</param>
        public unsafe void GetBoundsReferencesFromBroadPhase(out Vector3* min, out Vector3* max)
        {
            var index = Index;
            ref var collidable = ref Statics.Collidables[index];
            Debug.Assert(collidable.Shape.Exists, "Statics must have a shape. Something's not right here.");
            Statics.broadPhase.GetStaticBoundsPointers(collidable.BroadPhaseIndex, out min, out max);
        }

        /// <summary>
        /// 更新静电当前状态的宽泛阶段的界限。不包括速度扩展。如果静电没有形状,就什么都不做。
        /// </summary>
        /// <remarks>Can be useful if you made modifications to the static's state that you want reflected in the broad phase before the next timestep.
        /// 例如,如果要在直接移动对象后对宽相位执行光线投射,则必须更新它们的边界,否则宽相位边界将过期,光线可能会丢失。</备注>
        public void UpdateBounds()
        {
            Statics.UpdateBounds(Handle);
        }
    }
}
